/*
 * Copyright (C) 2011 TopCoder Inc., All Rights Reserved.
 */
package gov.nasa.pds.services.impl;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import gov.nasa.pds.entities.DataSet;
import gov.nasa.pds.entities.DataSetSearchCriteria;
import gov.nasa.pds.entities.HelpFile;
import gov.nasa.pds.entities.Instrument;
import gov.nasa.pds.entities.InstrumentHost;
import gov.nasa.pds.entities.MetadataObject;
import gov.nasa.pds.entities.Mission;
import gov.nasa.pds.entities.PagedResults;
import gov.nasa.pds.entities.Reference;
import gov.nasa.pds.entities.Target;
import gov.nasa.pds.entities.TargetType;
import gov.nasa.pds.entities.Volume;
import gov.nasa.pds.services.ConversionPersistence;
import gov.nasa.pds.services.DataDictionaryImportPersistence;
import gov.nasa.pds.services.DataSetService;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import junit.framework.JUnit4TestAdapter;

/**
 * <p>
 * The unit test of {@link JDBCDataSetService} class.
 * </p>
 *
 * @author TCSASSEMBLER
 * @version 1.0
 */
public class JDBCDataSetServiceTest {
    /**
     * The sql connection for test.
     */
    private Connection conn;

    /**
     * The application context for test.
     */
    private ApplicationContext context;

    /**
     * The conversion persistence for test.
     */
    private ConversionPersistence conversionPersistence;

    /**
     * The data dictionary import persistence for test.
     */
    private DataDictionaryImportPersistence dataDictionaryImportPersistence;

    /**
     * The dataSet service for test.
     */
    private DataSetService dataSetService;

    /**
     * Adapter for JUnit 3.
     *
     * @return a test suite.
     */
    public static junit.framework.Test suite() {
        return new JUnit4TestAdapter(JDBCDataSetServiceTest.class);
    }

    /**
     * Sets up the unit tests.
     *
     * @throws Exception to JUnit.
     */
    @Before
    public void setUp() throws Exception {
        conn = TestHelper.getConnection();
        context = new ClassPathXmlApplicationContext("beans.xml");
        conversionPersistence = (ConversionPersistence) context.getBean("conversionPersistence");
        dataDictionaryImportPersistence = (DataDictionaryImportPersistence) context.getBean(
                "dataDictionaryImportPersistence");
        dataSetService = (DataSetService) context.getBean("dataSetService");
    }

    /**
     * Tears down the test environment.
     *
     * @throws Exception to JUnit.
     */
    @After
    public void tearDown() throws Exception {
        try {
            TestHelper.deleteData(conn);
        } finally {
            TestHelper.closeConnection(conn);
        }
    }

    /**
     * Test method <code>getHelpFile(String name)</code>.
     *
     * @throws Exception to JUnit.
     */
    @Test
    public void testGetHelpFile() throws Exception {
        String name = "name";
        String path = "path";
        TestHelper.execute(conn, "insert into help_file (name, path) values ('" + name + "', '"
                + path  + "')");
        HelpFile helpFile = dataSetService.getHelpFile("name");
        assertTrue("'id' should be correct", helpFile.getId() > 0);
        assertEquals("'name' should be correct", name, helpFile.getName());
        assertEquals("'path' should be correct", path, helpFile.getPath());
    }

    /**
     * Test method <code>getHelpFile(String name)</code>.
     *
     * @throws Exception to JUnit.
     */
    @Test
    public void testGetHelpFileNotFound() throws Exception {
        String name = "name";
        String path = "path";
        TestHelper.execute(conn, "insert into help_file (name, path) values ('" + name + "', '"
                + path  + "')");
        HelpFile helpFile = dataSetService.getHelpFile("name2");
        assertNull("result should be correct", helpFile);
    }

    /**
     * Test method <code>getDataSet(long dataSetId)</code>.
     *
     * @throws Exception to JUnit.
     */
    @Test
    public void testGetDataSet() throws Exception {
        DataSet expected = createDataSet();
        insertDataSet(expected);
        DataSet dataset = dataSetService.getDataSet(expected.getId());

        assertEquals("'id' should be correct", expected.getId(), dataset.getId());
        assertEquals("'textId' should be correct", expected.getTextId(), dataset.getTextId());
        assertEquals("'name' should be correct", expected.getName(), dataset.getName());
        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd : hh mm ss");
        assertEquals("'startDate' should be correct", formatter.format(expected.getStartDate()),
                formatter.format(dataset.getStartDate()));
        assertEquals("'stopDate' should be correct", formatter.format(expected.getStopDate()),
                formatter.format(dataset.getStopDate()));
        assertEquals("'description' should be correct", expected.getDescription(), dataset.getDescription());
        assertEquals("'rating' should be correct", expected.getRating(), dataset.getRating());

        int i = 0;
        assertEquals("instrument size should be correct", expected.getInstruments().size(),
                dataset.getInstruments().size());
        for (Instrument instrument : dataset.getInstruments()) {
            assertEquals("instrument id should be correct", expected.getInstruments().get(i).getId(),
                    instrument.getId());
            i++;
        }

        i = 0;
        assertEquals("mission size should be correct", expected.getMissions().size(),
                dataset.getMissions().size());
        for (Mission mission : dataset.getMissions()) {
            assertEquals("mission id should be correct", expected.getMissions().get(i).getId(),
                    mission.getId());
            i++;
        }

        i = 0;
        assertEquals("reference size should be correct", expected.getReferences().size(),
                dataset.getReferences().size());
        for (Reference reference : dataset.getReferences()) {
            assertEquals("reference id should be correct", expected.getReferences().get(i).getId(),
                    reference.getId());
            i++;
        }

        i = 0;
        assertEquals("target size should be correct", expected.getTargets().size(),
                dataset.getTargets().size());
        for (Target target : dataset.getTargets()) {
            assertEquals("target id should be correct", expected.getTargets().get(i).getId(),
                    target.getId());
            i++;
        }

        i = 0;
        assertEquals("volume size should be correct", expected.getVolumes().size(),
                dataset.getVolumes().size());
        for (Volume volume : dataset.getVolumes()) {
            assertEquals("volume id should be correct", expected.getVolumes().get(i).getId(),
                    volume.getId());
            i++;
        }

        i = 0;
        assertEquals("children size should be correct", expected.getOtherChildren().size(),
                dataset.getOtherChildren().size());
        for (MetadataObject child : dataset.getOtherChildren()) {
            assertEquals("children id should be correct", expected.getOtherChildren().get(i).getId(),
                    child.getId());
            i++;
        }
    }

    /**
     * Test method <code>getDataSet(long dataSetId)</code>. When the dataset is not found.
     *
     * @throws Exception to JUnit.
     */
    @Test
    public void testGetDataSetNotFound() throws Exception {
        DataSet dataset = dataSetService.getDataSet(1);
        assertNull("The result should be null", dataset);
    }

    /**
     * Test method <code>searchDataSets(DataSetSearchCriteria criteria, int page,int pageSize)</code>.
     * Tests with instrument, target_type and target.
     *
     * @throws Exception to JUnit.
     */
    @Test
    public void testSearchDataSetsWithEmptyCriteria() throws Exception {
        DataSet[] expectedDataSets = new DataSet[3];

        expectedDataSets[0] = createDataSet();
        insertDataSet(expectedDataSets[0]);

        expectedDataSets[1] = createDataSet();
        insertDataSet(expectedDataSets[1]);

        expectedDataSets[2] = createDataSet();
        insertDataSet(expectedDataSets[2]);

        DataSetSearchCriteria criteria = new DataSetSearchCriteria();

        PagedResults<DataSet> result = dataSetService.searchDataSets(criteria, 1, 20);

        assertEquals("'total' should be correct", 3, result.getTotal());
        assertEquals("size should be correct", 3, result.getResults().size());

        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        for (int i = 0; i < 3; i++) {
            assertEquals("'id' should be correct", expectedDataSets[i].getId(), result.getResults().get(i).getId());
            assertEquals("'textId' should be correct", expectedDataSets[i].getTextId(),
                    result.getResults().get(i).getTextId());
            assertEquals("'name' should be correct", expectedDataSets[i].getName(),
                    result.getResults().get(i).getName());
            assertEquals("'startDate' should be correct", formatter.format(expectedDataSets[i].getStartDate()),
                    formatter.format(result.getResults().get(i).getStartDate()));
            assertEquals("'stopDate' should be correct", formatter.format(expectedDataSets[i].getStopDate()),
                    formatter.format(result.getResults().get(i).getStopDate()));
            assertEquals("'description' should be correct", expectedDataSets[i].getDescription(),
                    result.getResults().get(i).getDescription());
            assertEquals("'rating' should be correct", expectedDataSets[i].getRating(),
                    result.getResults().get(i).getRating());
        }

        // needn't check ids for volumes, targets and so on, as it calls getSupportingData which is same as
        // getDataSet().
    }

    /**
     * Test method <code>searchDataSets(DataSetSearchCriteria criteria, int page,int pageSize)</code>.
     * Tests with id, instrument and instrumentHost.
     *
     * @throws Exception to JUnit.
     */
    @Test
    public void testSearchDataSetsWithIdAndInstrumentAndHost() throws Exception {
        DataSet dataSet = createDataSet();
        insertDataSet(dataSet);

        insertDataSet(createDataSet());
        insertDataSet(createDataSet());
        insertDataSet(createDataSet());

        dataSet = createDataSet();
        dataSet.getInstruments().get(0).setName("instrumentName1");
        InstrumentHost instrumentHost = new InstrumentHost();
        instrumentHost.setName("hostName1");
        instrumentHost.setTextId("hostTextId");
        dataSet.getInstruments().get(0).setHosts(new ArrayList<InstrumentHost>());
        dataSet.getInstruments().get(0).getHosts().add(instrumentHost);
        dataSet.setRating(null);
        insertDataSet(dataSet);

        DataSetSearchCriteria criteria = new DataSetSearchCriteria();
        criteria.setId(dataSet.getId()); // last record
        List<String> hostNames = new ArrayList<String>();
        hostNames.add("hostName1");
        hostNames.add("hostName2");
        criteria.setInstrumentHosts(hostNames);
        List<String> instruments = new ArrayList<String>();
        instruments.add("instrumentName1");
        criteria.setInstruments(instruments);

        PagedResults<DataSet> result = dataSetService.searchDataSets(criteria, 1, 20);

        assertEquals("'total' should be correct", 1, result.getTotal());
        assertEquals("size should be correct", 1, result.getResults().size());

        assertEquals("'id' should be correct", dataSet.getId(), result.getResults().get(0).getId());
        assertEquals("'textId' should be correct", dataSet.getTextId(), result.getResults().get(0).getTextId());
        assertEquals("'name' should be correct", dataSet.getName(), result.getResults().get(0).getName());
        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        assertEquals("'startDate' should be correct", formatter.format(dataSet.getStartDate()),
                formatter.format(result.getResults().get(0).getStartDate()));
        assertEquals("'stopDate' should be correct", formatter.format(dataSet.getStopDate()),
                formatter.format(result.getResults().get(0).getStopDate()));
        assertEquals("'description' should be correct", dataSet.getDescription(),
                result.getResults().get(0).getDescription());
        assertEquals("'rating' should be correct", dataSet.getRating(), result.getResults().get(0).getRating());

        // needn't check ids for volumes, targets and so on, as it calls getSupportingData which is same as
        // getDataSet().
        // needn't check pagination, as it calls queryPagedDataSet(), which is same as
        // searchDataSets(String adHocQueryString, int page, int pageSize)
    }

    /**
     * Test method <code>searchDataSets(DataSetSearchCriteria criteria, int page,int pageSize)</code>.
     * Tests with lowerDataRating, mission and startDate. Also tests pagination.
     *
     * @throws Exception to JUnit.
     */
    @Test
    public void testSearchDataSetsWithLowerRatingAndMissionAndStartDate() throws Exception {
        DataSet[] expectedDataSets = new DataSet[2];
        DataSet dataSet = createDataSet();
        dataSet.setRating(1.2f);
        insertDataSet(dataSet);

        expectedDataSets[0] = createDataSet();
        expectedDataSets[0].setRating(1.9f);
        expectedDataSets[0].getMissions().get(0).setName("missionName1");
        expectedDataSets[0].getMissions().get(1).setName("missionName2");
        expectedDataSets[0].setStartDate(new Timestamp(System.currentTimeMillis()
                - 24 * 60 * 60 * 1000 * 3)); // 3 days ago
        insertDataSet(expectedDataSets[0]);

        expectedDataSets[1] = createDataSet();
        expectedDataSets[1].setRating(2.1f);
        expectedDataSets[1].getMissions().get(0).setName("missionName3");
        expectedDataSets[1].getMissions().get(1).setName("missionName4");
        expectedDataSets[1].setStartDate(new Timestamp(System.currentTimeMillis()
                - 24 * 60 * 60 * 1000 * 5)); // 5 days ago
        insertDataSet(expectedDataSets[1]);

        dataSet = createDataSet();
        dataSet.setRating(2.3f);
        dataSet.getMissions().get(0).setName("missionName5");
        dataSet.getMissions().get(1).setName("missionName6");
        insertDataSet(dataSet);

        dataSet = createDataSet();
        dataSet.setRating(2.5f);
        dataSet.getMissions().get(0).setName("missionName7");
        dataSet.getMissions().get(1).setName("missionName8");
        dataSet.setStartDate(new Timestamp(System.currentTimeMillis() - 24 * 60 * 60 * 1000 * 7)); // 7 days ago
        insertDataSet(dataSet);

        DataSetSearchCriteria criteria = new DataSetSearchCriteria();
        criteria.setLowerDataRating(1.5f);
        List<String> missionNames = new ArrayList<String>();
        missionNames.add("missionName1");
        missionNames.add("missionName3");
        missionNames.add("missionName4");
        missionNames.add("missionName7");
        criteria.setMissions(missionNames);
        criteria.setStartDate(new Timestamp(System.currentTimeMillis() - 24 * 60 * 60 * 1000 * 6)); // 6 days ago

        PagedResults<DataSet> result = dataSetService.searchDataSets(criteria, 1, 20);

        assertEquals("'total' should be correct", 2, result.getTotal());
        assertEquals("size should be correct", 2, result.getResults().size());

        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        for (int i = 0; i < 2; i++) {
            assertEquals("'id' should be correct", expectedDataSets[i].getId(),
                    result.getResults().get(i).getId());
            assertEquals("'textId' should be correct", expectedDataSets[i].getTextId(),
                    result.getResults().get(i).getTextId());
            assertEquals("'name' should be correct", expectedDataSets[i].getName(),
                    result.getResults().get(i).getName());
            assertEquals("'startDate' should be correct", formatter.format(expectedDataSets[i].getStartDate()),
                    formatter.format(result.getResults().get(i).getStartDate()));
            assertEquals("'stopDate' should be correct", formatter.format(expectedDataSets[i].getStopDate()),
                    formatter.format(result.getResults().get(i).getStopDate()));
            assertEquals("'description' should be correct", expectedDataSets[i].getDescription(),
                    result.getResults().get(i).getDescription());
            assertEquals("'rating' should be correct", expectedDataSets[i].getRating(),
                    result.getResults().get(i).getRating());
        }

        // Check pagination
        result = dataSetService.searchDataSets(criteria, 1, 1);

        assertEquals("'total' should be correct", 2, result.getTotal());
        assertEquals("size should be correct", 1, result.getResults().size());

        assertEquals("'id' should be correct", expectedDataSets[0].getId(), result.getResults().get(0).getId());
        assertEquals("'textId' should be correct", expectedDataSets[0].getTextId(),
                result.getResults().get(0).getTextId());
        assertEquals("'name' should be correct", expectedDataSets[0].getName(), result.getResults().get(0).getName());
        assertEquals("'startDate' should be correct", formatter.format(expectedDataSets[0].getStartDate()),
                formatter.format(result.getResults().get(0).getStartDate()));
        assertEquals("'stopDate' should be correct", formatter.format(expectedDataSets[0].getStopDate()),
                formatter.format(result.getResults().get(0).getStopDate()));
        assertEquals("'description' should be correct", expectedDataSets[0].getDescription(),
                result.getResults().get(0).getDescription());
        assertEquals("'rating' should be correct", expectedDataSets[0].getRating(),
                result.getResults().get(0).getRating());

        result = dataSetService.searchDataSets(criteria, 2, 1);

        assertEquals("'total' should be correct", 2, result.getTotal());
        assertEquals("size should be correct", 1, result.getResults().size());

        assertEquals("'id' should be correct", expectedDataSets[1].getId(), result.getResults().get(0).getId());
        assertEquals("'textId' should be correct", expectedDataSets[1].getTextId(),
                result.getResults().get(0).getTextId());
        assertEquals("'name' should be correct", expectedDataSets[1].getName(), result.getResults().get(0).getName());
        assertEquals("'startDate' should be correct", formatter.format(expectedDataSets[1].getStartDate()),
                formatter.format(result.getResults().get(0).getStartDate()));
        assertEquals("'stopDate' should be correct", formatter.format(expectedDataSets[1].getStopDate()),
                formatter.format(result.getResults().get(0).getStopDate()));
        assertEquals("'description' should be correct", expectedDataSets[1].getDescription(),
                result.getResults().get(0).getDescription());
        assertEquals("'rating' should be correct", expectedDataSets[1].getRating(),
                result.getResults().get(0).getRating());

        result = dataSetService.searchDataSets(criteria, 3, 1);

        assertEquals("'total' should be correct", 2, result.getTotal());
        assertEquals("size should be correct", 0, result.getResults().size());
        // needn't check ids for volumes, targets and so on, as it calls getSupportingData which is same as
        // getDataSet().
    }

    /**
     * Test method <code>searchDataSets(DataSetSearchCriteria criteria, int page,int pageSize)</code>.
     * Tests with upperDataRating, target and stopDate. Also tests pagination.
     *
     * @throws Exception to JUnit.
     */
    @Test
    public void testSearchDataSetsWithUpperRatingAndTargetAndStopDate() throws Exception {
        DataSet[] expectedDataSets = new DataSet[3];
        DataSet dataSet = createDataSet();
        dataSet.setRating(1.2f);
        insertDataSet(dataSet);

        expectedDataSets[0] = createDataSet();
        expectedDataSets[0].setRating(1.9f);
        expectedDataSets[0].getTargets().get(0).setName("targetName1");
        expectedDataSets[0].getTargets().get(1).setName("targetName2");
        expectedDataSets[0].setStopDate(new Timestamp(System.currentTimeMillis()
                + 24 * 60 * 60 * 1000 * 3)); // 3 days ago
        insertDataSet(expectedDataSets[0]);

        dataSet = createDataSet();
        dataSet.setRating(2.9f);
        dataSet.getTargets().get(0).setName("targetName3");
        dataSet.getTargets().get(1).setName("targetName4");
        dataSet.setStopDate(new Timestamp(System.currentTimeMillis() + 24 * 60 * 60 * 1000 * 4)); // 4 days ago
        insertDataSet(dataSet);

        expectedDataSets[1] = createDataSet();
        expectedDataSets[1].setRating(2.1f);
        expectedDataSets[1].getTargets().get(0).setName("targetName5");
        expectedDataSets[1].getTargets().get(1).setName("targetName6");
        expectedDataSets[1].setStopDate(new Timestamp(System.currentTimeMillis()
                + 24 * 60 * 60 * 1000 * 5)); // 5 days ago
        insertDataSet(expectedDataSets[1]);

        expectedDataSets[2] = createDataSet();
        expectedDataSets[2].setRating(1.3f);
        expectedDataSets[2].getTargets().get(0).setName("targetName7");
        expectedDataSets[2].getTargets().get(1).setName("targetName8");
        expectedDataSets[2].setStopDate(new Timestamp(System.currentTimeMillis()
                + 24 * 60 * 60 * 1000 * 7)); // 7 days ago
        insertDataSet(expectedDataSets[2]);

        dataSet = createDataSet();
        dataSet.setRating(2.5f);
        dataSet.getTargets().get(0).setName("targetName9");
        dataSet.getTargets().get(1).setName("targetName10");
        dataSet.setStopDate(new Timestamp(System.currentTimeMillis() + 24 * 60 * 60 * 1000 * 9)); // 9 days ago
        insertDataSet(dataSet);

        DataSetSearchCriteria criteria = new DataSetSearchCriteria();
        criteria.setUpperDataRating(2.1f);
        List<String> targetNames = new ArrayList<String>();
        targetNames.add("targetName1");
        targetNames.add("targetName6");
        targetNames.add("targetName7");
        targetNames.add("targetName9");
        criteria.setTargets(targetNames);
        criteria.setStopDate(new Timestamp(System.currentTimeMillis() + 24 * 60 * 60 * 1000 * 8)); // 8 days ago

        PagedResults<DataSet> result = dataSetService.searchDataSets(criteria, 1, 20);

        assertEquals("'total' should be correct", 3, result.getTotal());
        assertEquals("size should be correct", 3, result.getResults().size());

        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        for (int i = 0; i < 3; i++) {
            assertEquals("'id' should be correct", expectedDataSets[i].getId(),
                    result.getResults().get(i).getId());
            assertEquals("'textId' should be correct", expectedDataSets[i].getTextId(),
                    result.getResults().get(i).getTextId());
            assertEquals("'name' should be correct", expectedDataSets[i].getName(),
                    result.getResults().get(i).getName());
            assertEquals("'startDate' should be correct", formatter.format(expectedDataSets[i].getStartDate()),
                    formatter.format(result.getResults().get(i).getStartDate()));
            assertEquals("'stopDate' should be correct", formatter.format(expectedDataSets[i].getStopDate()),
                    formatter.format(result.getResults().get(i).getStopDate()));
            assertEquals("'description' should be correct", expectedDataSets[i].getDescription(),
                    result.getResults().get(i).getDescription());
            assertEquals("'rating' should be correct", expectedDataSets[i].getRating(),
                    result.getResults().get(i).getRating());
        }

        // Check pagination
        result = dataSetService.searchDataSets(criteria, 1, 2);

        assertEquals("'total' should be correct", 3, result.getTotal());
        assertEquals("size should be correct", 2, result.getResults().size());

        for (int i = 0; i < 2; i++) {
            assertEquals("'id' should be correct", expectedDataSets[i].getId(),
                    result.getResults().get(i).getId());
            assertEquals("'textId' should be correct", expectedDataSets[i].getTextId(),
                    result.getResults().get(i).getTextId());
            assertEquals("'name' should be correct", expectedDataSets[i].getName(),
                    result.getResults().get(i).getName());
            assertEquals("'startDate' should be correct", formatter.format(expectedDataSets[i].getStartDate()),
                    formatter.format(result.getResults().get(i).getStartDate()));
            assertEquals("'stopDate' should be correct", formatter.format(expectedDataSets[i].getStopDate()),
                    formatter.format(result.getResults().get(i).getStopDate()));
            assertEquals("'description' should be correct", expectedDataSets[i].getDescription(),
                    result.getResults().get(i).getDescription());
            assertEquals("'rating' should be correct", expectedDataSets[i].getRating(),
                    result.getResults().get(i).getRating());
        }

        result = dataSetService.searchDataSets(criteria, 2, 2);

        assertEquals("'total' should be correct", 3, result.getTotal());
        assertEquals("size should be correct", 1, result.getResults().size());

        assertEquals("'id' should be correct", expectedDataSets[2].getId(), result.getResults().get(0).getId());
        assertEquals("'textId' should be correct", expectedDataSets[2].getTextId(),
                result.getResults().get(0).getTextId());
        assertEquals("'name' should be correct", expectedDataSets[2].getName(), result.getResults().get(0).getName());
        assertEquals("'startDate' should be correct", formatter.format(expectedDataSets[2].getStartDate()),
                formatter.format(result.getResults().get(0).getStartDate()));
        assertEquals("'stopDate' should be correct", formatter.format(expectedDataSets[2].getStopDate()),
                formatter.format(result.getResults().get(0).getStopDate()));
        assertEquals("'description' should be correct", expectedDataSets[2].getDescription(),
                result.getResults().get(0).getDescription());
        assertEquals("'rating' should be correct", expectedDataSets[2].getRating(),
                result.getResults().get(0).getRating());

        result = dataSetService.searchDataSets(criteria, 3, 2);

        assertEquals("'total' should be correct", 3, result.getTotal());
        assertEquals("size should be correct", 0, result.getResults().size());
        // needn't check ids for volumes, targets and so on, as it calls getSupportingData which is same as
        // getDataSet().
    }

    /**
     * Test method <code>searchDataSets(DataSetSearchCriteria criteria, int page,int pageSize)</code>.
     * Tests with instrument, target_type and target.
     *
     * @throws Exception to JUnit.
     */
    @Test
    public void testSearchDataSetsWithInstrumentAndTargetTypeAndTarget() throws Exception {
        List<TargetType> targetTypes = new ArrayList<TargetType>();
        TargetType targetType;
        for (int i = 1; i < 7; i++) {
            targetType = new TargetType();
            targetType.setName("targetTypeName" + i);
            targetTypes.add(targetType);
        }
        dataDictionaryImportPersistence.insertTargetTypes(targetTypes);

        DataSet[] expectedDataSets = new DataSet[3];

        DataSet dataSet = createDataSet();
        dataSet.getInstruments().get(0).setName("instrumentName1");
        dataSet.getTargets().get(0).setName("targetName1");
        dataSet.getTargets().get(1).setName("targetName2");
        dataSet.getTargets().get(0).setTypes(new ArrayList<TargetType>());
        dataSet.getTargets().get(0).getTypes().add(targetTypes.get(0));
        insertDataSet(dataSet);

        expectedDataSets[0] = createDataSet();
        expectedDataSets[0].getInstruments().get(1).setName("instrumentName2");
        expectedDataSets[0].getTargets().get(0).setName("targetName3");
        expectedDataSets[0].getTargets().get(1).setName("targetName4");
        expectedDataSets[0].getTargets().get(1).setTypes(new ArrayList<TargetType>());
        expectedDataSets[0].getTargets().get(1).getTypes().add(targetTypes.get(1));
        insertDataSet(expectedDataSets[0]);

        dataSet = createDataSet();
        dataSet.getInstruments().get(0).setName("instrumentName3");
        dataSet.getTargets().get(0).setName("targetName5");
        dataSet.getTargets().get(1).setName("targetName6");
        dataSet.getTargets().get(0).setTypes(new ArrayList<TargetType>());
        dataSet.getTargets().get(0).getTypes().add(targetTypes.get(2));
        insertDataSet(dataSet);

        expectedDataSets[1] = createDataSet();
        expectedDataSets[1].getInstruments().get(1).setName("instrumentName4");
        expectedDataSets[1].getTargets().get(0).setName("targetName7");
        expectedDataSets[1].getTargets().get(1).setName("targetName8");
        expectedDataSets[1].getTargets().get(1).setTypes(new ArrayList<TargetType>());
        expectedDataSets[1].getTargets().get(1).getTypes().add(targetTypes.get(3));
        insertDataSet(expectedDataSets[1]);

        expectedDataSets[2] = createDataSet();
        expectedDataSets[2].getInstruments().get(0).setName("instrumentName5");
        expectedDataSets[2].getTargets().get(0).setName("targetName9");
        expectedDataSets[2].getTargets().get(1).setName("targetName10");
        expectedDataSets[2].getTargets().get(0).setTypes(new ArrayList<TargetType>());
        expectedDataSets[2].getTargets().get(0).getTypes().add(targetTypes.get(4));
        insertDataSet(expectedDataSets[2]);

        dataSet = createDataSet();
        dataSet.getInstruments().get(1).setName("instrumentName6");
        dataSet.getTargets().get(0).setName("targetName11");
        dataSet.getTargets().get(1).setName("targetName12");
        dataSet.getTargets().get(1).setTypes(new ArrayList<TargetType>());
        dataSet.getTargets().get(1).getTypes().add(targetTypes.get(5));
        insertDataSet(dataSet);

        DataSetSearchCriteria criteria = new DataSetSearchCriteria();
        List<String> instrumentNames = new ArrayList<String>();
        instrumentNames.add("instrumentName1");
        instrumentNames.add("instrumentName2");
        instrumentNames.add("instrumentName4");
        instrumentNames.add("instrumentName5");
        criteria.setInstruments(instrumentNames);
        List<String> targetNames = new ArrayList<String>();
        targetNames.add("targetName3");
        targetNames.add("targetName4");
        targetNames.add("targetName7");
        targetNames.add("targetName8");
        targetNames.add("targetName9");
        targetNames.add("targetName12");
        criteria.setTargets(targetNames);
        List<String> targetTypeNames = new ArrayList<String>();
        targetTypeNames.add("targetTypeName2");
        targetTypeNames.add("targetTypeName4");
        targetTypeNames.add("targetTypeName5");
        targetTypeNames.add("targetTypeName6");
        criteria.setTargetTypes(targetTypeNames);

        PagedResults<DataSet> result = dataSetService.searchDataSets(criteria, 1, 20);

        assertEquals("'total' should be correct", 3, result.getTotal());
        assertEquals("size should be correct", 3, result.getResults().size());

        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        for (int i = 0; i < 3; i++) {
            assertEquals("'id' should be correct", expectedDataSets[i].getId(), result.getResults().get(i).getId());
            assertEquals("'textId' should be correct", expectedDataSets[i].getTextId(),
                    result.getResults().get(i).getTextId());
            assertEquals("'name' should be correct", expectedDataSets[i].getName(),
                    result.getResults().get(i).getName());
            assertEquals("'startDate' should be correct", formatter.format(expectedDataSets[i].getStartDate()),
                    formatter.format(result.getResults().get(i).getStartDate()));
            assertEquals("'stopDate' should be correct", formatter.format(expectedDataSets[i].getStopDate()),
                    formatter.format(result.getResults().get(i).getStopDate()));
            assertEquals("'description' should be correct", expectedDataSets[i].getDescription(),
                    result.getResults().get(i).getDescription());
            assertEquals("'rating' should be correct", expectedDataSets[i].getRating(),
                    result.getResults().get(i).getRating());
        }

        // needn't check ids for volumes, targets and so on, as it calls getSupportingData which is same as
        // getDataSet().
    }

    /**
     * Test method <code>searchDataSets(DataSetSearchCriteria criteria, int page,int pageSize)</code>.
     * Tests with upperDataRating, whiteSpotRatingThreshold and whiteSpotRatingPercentThreshold.
     *
     * @throws Exception to JUnit.
     */
    @Test
    public void testSearchDataSetsWithUpperRatingAndRatingThresholds() throws Exception {
        DataSet[] expectedDataSets = new DataSet[3];
        DataSet dataSet = createDataSet();
        dataSet.setRating(4.2f);
        insertDataSet(dataSet);

        expectedDataSets[0] = createDataSet();
        expectedDataSets[0].setRating(2.9f);
        insertDataSet(expectedDataSets[0]);

        dataSet = createDataSet();
        dataSet.setRating(2.1f);
        insertDataSet(dataSet);

        expectedDataSets[1] = createDataSet();
        expectedDataSets[1].setRating(2.8f);
        insertDataSet(expectedDataSets[1]);

        expectedDataSets[2] = createDataSet();
        expectedDataSets[2].setRating(3.4f);
        insertDataSet(expectedDataSets[2]);

        DataSetSearchCriteria criteria = new DataSetSearchCriteria();
        criteria.setUpperDataRating(3.5f);
        criteria.setWhiteSpots(true);

        PagedResults<DataSet> result = dataSetService.searchDataSets(criteria, 1, 20);

        assertEquals("'total' should be correct", 3, result.getTotal());
        assertEquals("size should be correct", 3, result.getResults().size());

        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        for (int i = 0; i < 3; i++) {
            assertEquals("'id' should be correct", expectedDataSets[i].getId(), result.getResults().get(i).getId());
            assertEquals("'textId' should be correct", expectedDataSets[i].getTextId(),
                    result.getResults().get(i).getTextId());
            assertEquals("'name' should be correct", expectedDataSets[i].getName(),
                    result.getResults().get(i).getName());
            assertEquals("'startDate' should be correct", formatter.format(expectedDataSets[i].getStartDate()),
                    formatter.format(result.getResults().get(i).getStartDate()));
            assertEquals("'stopDate' should be correct", formatter.format(expectedDataSets[i].getStopDate()),
                    formatter.format(result.getResults().get(i).getStopDate()));
            assertEquals("'description' should be correct", expectedDataSets[i].getDescription(),
                    result.getResults().get(i).getDescription());
            assertEquals("'rating' should be correct", expectedDataSets[i].getRating(),
                    result.getResults().get(i).getRating());
        }

        // needn't check ids for volumes, targets and so on, as it calls getSupportingData which is same as
        // getDataSet().
    }

    /**
     * Test method <code>searchDataSets(String adHocQueryString, int page, int pageSize)</code>.
     *
     * @throws Exception to JUnit.
     */
    @Test
    public void testSearchDataSetsAdHocQueryStringPaging() throws Exception {
        DataSet[] expectedDataSets = new DataSet[40];
        for (int i = 0; i < 40; i++) {
            expectedDataSets[i] = createDataSet();
            insertDataSet(expectedDataSets[i]);
        }
        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

        PagedResults<DataSet> result = dataSetService.searchDataSets("select * from dataset", 2, 15);
        assertEquals("'total' should be correct", 40, result.getTotal());
        assertEquals("size should be correct", 15, result.getResults().size());
        for (int i = 15; i < 30; i++) {
            assertEquals("'id' should be correct", (long) expectedDataSets[i].getId(),
                    result.getResults().get(i - 15).getId());
            assertEquals("'textId' should be correct", expectedDataSets[i].getTextId(),
                    result.getResults().get(i - 15).getTextId());
            assertEquals("'name' should be correct", expectedDataSets[i].getName(),
                    result.getResults().get(i - 15).getName());
            assertEquals("'startDate' should be correct", formatter.format(expectedDataSets[i].getStartDate()),
                    formatter.format(result.getResults().get(i - 15).getStartDate()));
            assertEquals("'stopDate' should be correct", formatter.format(expectedDataSets[i].getStopDate()),
                    formatter.format(result.getResults().get(i - 15).getStopDate()));
            assertEquals("'description' should be correct", expectedDataSets[i].getDescription(),
                    result.getResults().get(i - 15).getDescription());
            assertEquals("'rating' should be correct", expectedDataSets[i].getRating(),
                    result.getResults().get(i - 15).getRating());
        }
        ResultSet resultSet = TestHelper.query(conn, "Select * from popular_query");
        int j = 0;
        while (resultSet.next()) {
            assertEquals("'query' should be correct", "select * from dataset",
                    resultSet.getString("query"));
            assertEquals("'usage_frequency' should be correct", 0.00,
                   resultSet.getDouble("usage_frequency"), 0.00);
            assertEquals("'usage_count' should be correct", 1,
                        resultSet.getInt("usage_count"));
            j++;
        }
        assertEquals("should be only one record", 1, j);

        // Tests pagination
        result = dataSetService.searchDataSets("select * from dataset", 3, 15);
        assertEquals("'total' should be correct", 40, result.getTotal());
        assertEquals("size should be correct", 10, result.getResults().size());
        for (int i = 30; i < 40; i++) {
            assertEquals("'id' should be correct", (long) expectedDataSets[i].getId(),
                    result.getResults().get(i - 30).getId());
        }
        resultSet = TestHelper.query(conn, "Select * from popular_query");
        j = 0;
        while (resultSet.next()) {
            assertEquals("'query' should be correct", "select * from dataset",
                    resultSet.getString("query"));
            assertEquals("'usage_frequency' should be correct", 0.00,
                   resultSet.getDouble("usage_frequency"), 0.00);
            assertEquals("'usage_count' should be correct", 2,
                        resultSet.getInt("usage_count"));
            j++;
        }
        assertEquals("should be only one record", 1, j);

        result = dataSetService.searchDataSets("select * from dataset", 1, 50);
        assertEquals("'total' should be correct", 40, result.getTotal());
        assertEquals("size should be correct", 40, result.getResults().size());
        for (int i = 0; i < 40; i++) {
            assertEquals("'id' should be correct", (long) expectedDataSets[i].getId(),
                    result.getResults().get(i).getId());
        }
        resultSet = TestHelper.query(conn, "Select * from popular_query");
        j = 0;
        while (resultSet.next()) {
            assertEquals("'query' should be correct", "select * from dataset",
                    resultSet.getString("query"));
            assertEquals("'usage_frequency' should be correct", 0.00,
                   resultSet.getDouble("usage_frequency"), 0.00);
            assertEquals("'usage_count' should be correct", 3,
                        resultSet.getInt("usage_count"));
            j++;
        }
        assertEquals("should be only one record", 1, j);

        // needn't check ids for volumes, targets and so on, as it calls getSupportingData which is same as
        // getDataSet().
    }

    /**
     * Test method <code>getRelatedNames(Class&lt;?&gt; clazz, String keyword)</code>. For datasets.
     *
     * @throws Exception to JUnit.
     */
    @Test
    public void testGetRelatedNamesWithDataSets() throws Exception {
        for (int i = 0; i < 5; i++) {
            DataSet dataSet = new DataSet();
            dataSet.setDescription("description");
            dataSet.setName("name" + i);
            dataSet.setRating(1.1f);
            dataSet.setStartDate(new Timestamp(System.currentTimeMillis()));
            dataSet.setStopDate(new Timestamp(System.currentTimeMillis()));
            dataSet.setTextId("textId");
            conversionPersistence.insertDataSet(dataSet);
        }
        for (int i = 0; i < 10; i++) {
            DataSet dataSet = new DataSet();
            dataSet.setDescription("description");
            dataSet.setName("different" + i);
            dataSet.setRating(1.1f);
            dataSet.setStartDate(new Timestamp(System.currentTimeMillis()));
            dataSet.setStopDate(new Timestamp(System.currentTimeMillis()));
            dataSet.setTextId("textId");
            conversionPersistence.insertDataSet(dataSet);
        }
        List<String> result = dataSetService.getRelatedNames(DataSet.class, "ame");

        assertEquals("size should be correct", 5, result.size());

        for (int i = 0; i < 5; i++) {
            assertEquals("'name' should be correct", "name" + i, result.get(i));
        }
    }

    /**
     * Test method <code>getRelatedNames(Class&lt;?&gt; clazz, String keyword)</code>. For missions.
     *
     * @throws Exception to JUnit.
     */
    @Test
    public void testGetRelatedNamesWithMissions() throws Exception {
        for (int i = 0; i < 10; i++) {
            Mission mission = new Mission();
            mission.setDescription("description" + i);
            mission.setEndDate(new Timestamp(System.currentTimeMillis()));
            mission.setName("name" + i);
            mission.setStartDate(new Timestamp(System.currentTimeMillis()));
            conversionPersistence.insertMission(mission);
        }
        for (int i = 0; i < 5; i++) {
            Mission mission = new Mission();
            mission.setDescription("description" + i);
            mission.setEndDate(new Timestamp(System.currentTimeMillis()));
            mission.setName("different" + i);
            mission.setStartDate(new Timestamp(System.currentTimeMillis()));
            conversionPersistence.insertMission(mission);
        }
        List<String> result = dataSetService.getRelatedNames(Mission.class, "ame");

        assertEquals("size should be correct", 10, result.size());

        for (int i = 0; i < 10; i++) {
            assertEquals("'name' should be correct", "name" + i, result.get(i));
        }
    }

    /**
     * Test method <code>getRelatedNames(Class&lt;?&gt; clazz, String keyword)</code>. For instruments.
     *
     * @throws Exception to JUnit.
     */
    @Test
    public void testGetRelatedNamesWithInstruments() throws Exception {
        for (int i = 0; i < 15; i++) {
            Instrument instrument = new Instrument();
            instrument.setDescription("description");
            instrument.setName("name" + i);
            instrument.setTextId("textId");
            instrument.setType("type");
            conversionPersistence.insertInstrument(instrument);
        }
        for (int i = 0; i < 5; i++) {
            Instrument instrument = new Instrument();
            instrument.setDescription("description");
            instrument.setName("different" + i);
            instrument.setTextId("textId");
            instrument.setType("type");
            conversionPersistence.insertInstrument(instrument);
        }
        List<String> result = dataSetService.getRelatedNames(Instrument.class, "ame");

        assertEquals("size should be correct", 15, result.size());

        for (int i = 0; i < 15; i++) {
            assertEquals("'name' should be correct", "name" + i, result.get(i));
        }
    }

    /**
     * Test method <code>getRelatedNames(Class&lt;?&gt; clazz, String keyword)</code>. For target types.
     *
     * @throws Exception to JUnit.
     */
    @Test
    public void testGetRelatedNamesWithTargetTypes() throws Exception {
        for (int i = 0; i < 11; i++) {
            List<TargetType> targetTypes = new ArrayList<TargetType>();
            TargetType targetType = new TargetType();
            targetType.setName("name" + i);
            targetTypes.add(targetType);

            dataDictionaryImportPersistence.insertTargetTypes(targetTypes);
        }
        for (int i = 0; i < 5; i++) {
            List<TargetType> targetTypes = new ArrayList<TargetType>();
            TargetType targetType = new TargetType();
            targetType.setName("different" + i);
            targetTypes.add(targetType);

            dataDictionaryImportPersistence.insertTargetTypes(targetTypes);
        }
        List<String> result = dataSetService.getRelatedNames(TargetType.class, "ame");

        assertEquals("size should be correct", 11, result.size());

        for (int i = 0; i < 11; i++) {
            assertEquals("'name' should be correct", "name" + i, result.get(i));
        }
    }

    /**
     * Test method <code>getRelatedNames(Class&lt;?&gt; clazz, String keyword)</code>. For targets.
     *
     * @throws Exception to JUnit.
     */
    @Test
    public void testGetRelatedNamesWithTargets() throws Exception {
        for (int i = 0; i < 7; i++) {
            Target target = new Target();
            target.setName("name" + i);
            conversionPersistence.insertTarget(target);
        }
        for (int i = 0; i < 5; i++) {
            Target target = new Target();
            target.setName("different" + i);
            conversionPersistence.insertTarget(target);
        }
        List<String> result = dataSetService.getRelatedNames(Target.class, "ame");

        assertEquals("size should be correct", 7, result.size());

        for (int i = 0; i < 7; i++) {
            assertEquals("'name' should be correct", "name" + i, result.get(i));
        }
    }

    /**
     * Test method <code>searchDataSetsByPredefinedQuery(String predefinedQueryName, int page, int pageSize)</code>.
     *
     * @throws Exception to JUnit.
     */
    @Test
    public void testSearchDataSetsByPredefinedQuery() throws Exception {
        List<Long> ids = new ArrayList<Long>();
        for (int i = 0; i < 40; i++) {
            ids.add(insertDataSet(createDataSet()));
        }
        TestHelper.execute(conn, "insert into predefined_query (name, query, description) values"
            + " ('predefinedName', 'select * from dataset', 'description')");
        PagedResults<DataSet> result = dataSetService.searchDataSetsByPredefinedQuery("predefinedName", 2, 15);

        assertEquals("'total' should be correct", 40, result.getTotal());
        assertEquals("size should be correct", 15, result.getResults().size());

        for (int i = 15; i < 30; i++) {
            assertEquals("'id' should be correct", (long) ids.get(i), result.getResults().get(i - 15).getId());
        }

        // needn't check pagination, as it calls queryPagedDataSet(), which is same as
        // searchDataSets(String adHocQueryString, int page, int pageSize)
        // needn't check ids for volumes, targets and so on, as it calls getSupportingData which is same as
        // getDataSet().
    }

    /**
     * Test method <code>searchDataSetsByPredefinedQuery(String predefinedQueryName, int page,
     * int pageSize)</code>.
     * Tests with a predefinedQueryName that is not found in database.
     *
     * @throws Exception to JUnit.
     */
    @Test
    public void testSearchDataSetsByPredefinedQueryWithQueryNotFound() throws Exception {
        List<Long> ids = new ArrayList<Long>();
        for (int i = 0; i < 40; i++) {
            ids.add(insertDataSet(createDataSet()));
        }
        TestHelper.execute(conn, "insert into predefined_query (name, query, description) values"
            + " ('different', 'select * from dataset', 'description')");
        PagedResults<DataSet> result = dataSetService.searchDataSetsByPredefinedQuery("predefinedName", 2, 15);

        assertEquals("'total' should be correct", 0, result.getTotal());
        assertEquals("size should be correct", 0, result.getResults().size());

        // needn't check textId, name and so on, as it calls queryPagedDataSet which is same as
        // searchDataSets() by criteria.
        // needn't check pagination, as it calls queryPagedDataSet(), which is same as
        // searchDataSets(String adHocQueryString, int page, int pageSize)
        // needn't check ids for volumes, targets and so on, as it calls getSupportingData which is same as
        // getDataSet().
    }

    /**
     * Test method <code>getPredefinedQueries()</code>.
     *
     * @throws Exception to JUnit.
     */
    @Test
    public void testGetPredefinedQueries() throws Exception {
        String name = "name";
        String query = "query";
        String description = "description";
        for (int i = 0; i < 100; i++) {
            TestHelper.execute(conn, "insert into predefined_query (name, query, description) values ('"
                    + (name + i) + "', '" + (query + i) + "', '" + (description + i)  + "')");
        }
        List<String> result = dataSetService.getPredefinedQueries();
        for (int i = 0; i < 100; i++) {
            assertEquals("'query' should be correct", (query + i), result.get(i));
        }
    }

    /**
     * Test method <code>getPredefinedQueries()</code>.
     *
     * @throws Exception to JUnit.
     */
    @Test
    public void testGetPredefinedQueriesNullResult() throws Exception {
        assertTrue("result should be correct", dataSetService.getPredefinedQueries().isEmpty());
    }

    /**
     * Test method <code>getPopularQueries()</code>.
     *
     * @throws Exception to JUnit.
     */
    @Test
    public void testGetPopularQueries() throws Exception {
        String query = "query";
        for (int i = 0; i < 100; i++) {
            TestHelper.execute(conn, "insert into popular_query (query, usage_frequency, usage_count) values ('"
                    + (query + i) + "', 0, '" + i  + "')");
        }
        List<String> result = dataSetService.getPopularQueries();
        for (int i = 0; i < 10; i++) {
            assertEquals("'query' should be correct", (query + (100 - i - 1)), result.get(i));
        }
    }

    /**
     * Test method <code>getPopularQueries()</code>.
     *
     * @throws Exception to JUnit.
     */
    @Test
    public void testGetPopularQueriesNullResult() throws Exception {
        assertTrue("result should be correct", dataSetService.getPopularQueries().isEmpty());
    }

    /**
     * Inserts a dataset.
     *
     * @return the created dataset
     * @throws Exception to JUnit.
     */
    private DataSet createDataSet() throws Exception {
        DataSet dataSet = new DataSet();
        dataSet.setDescription("description");
        dataSet.setName("name");
        dataSet.setRating(1.1f);
        dataSet.setStartDate(new Timestamp(System.currentTimeMillis()));
        dataSet.setStopDate(new Timestamp(System.currentTimeMillis()));
        dataSet.setTextId("textId");

        // references
        dataSet.setReferences(new ArrayList<Reference>());
        Reference reference = new Reference();
        reference.setDescription("description1");
        reference.setKeyTextId("keyTextId1");
        dataSet.getReferences().add(reference);
        reference = new Reference();
        reference.setDescription("description2");
        reference.setKeyTextId("keyTextId2");
        dataSet.getReferences().add(reference);

        // other children
        dataSet.setOtherChildren(new ArrayList<MetadataObject>());
        dataSet.getOtherChildren().add(TestHelper.createMetadataObject("name1"));
        dataSet.getOtherChildren().get(0).getProperties().add(TestHelper.createProperty("name2", "value1", "value2"));
        dataSet.getOtherChildren().get(0).setChildren(new ArrayList<MetadataObject>());
        dataSet.getOtherChildren().get(0).getChildren().add(TestHelper.createMetadataObject("name3"));
        dataSet.getOtherChildren().get(0).getChildren().get(0).getProperties()
            .add(TestHelper.createProperty("name4", "value3", "value4"));
        dataSet.getOtherChildren().get(0).getChildren().get(0).getProperties()
            .add(TestHelper.createProperty("name5", "value5", "value6"));
        dataSet.getOtherChildren().get(0).getChildren().add(TestHelper.createMetadataObject("name6"));
        dataSet.getOtherChildren().get(0).getChildren().get(1).setProperties(null);

        // as insertInstrument(Instrument instrument), insertMissions(Mission mission).
        // insertTarget(Target target) and  insertTarget(Target target) are called
        // so only check the records in instrument and dataset_instrument tables, ....
        dataSet.setInstruments(new ArrayList<Instrument>());
        Instrument instrument = new Instrument();
        instrument.setDescription("description1");
        instrument.setName("name1");
        instrument.setTextId("textId1");
        instrument.setType("type1");
        dataSet.getInstruments().add(instrument);
        instrument = new Instrument();
        instrument.setDescription("description2");
        instrument.setName("name2");
        instrument.setTextId("textId2");
        instrument.setType("type2");
        dataSet.getInstruments().add(instrument);

        dataSet.setMissions(new ArrayList<Mission>());
        Mission mission = new Mission();
        mission.setDescription("description1");
        mission.setEndDate(new Timestamp(System.currentTimeMillis()));
        mission.setName("name1");
        mission.setStartDate(new Timestamp(System.currentTimeMillis()));
        dataSet.getMissions().add(mission);
        mission = new Mission();
        mission.setDescription("description2");
        mission.setEndDate(new Timestamp(System.currentTimeMillis()));
        mission.setName("name2");
        mission.setStartDate(new Timestamp(System.currentTimeMillis()));
        dataSet.getMissions().add(mission);

        dataSet.setTargets(new ArrayList<Target>());
        Target target = new Target();
        target.setName("name1");
        dataSet.getTargets().add(target);
        target = new Target();
        target.setName("name2");
        dataSet.getTargets().add(target);

        dataSet.setVolumes(new ArrayList<Volume>());
        Volume volume = new Volume();
        volume.setName("name1");
        volume.setDescription("description1");
        volume.setTextId("textId1");
        volume.setSetTextId("setTextId1");
        volume.setSetName("setName1");
        volume.setSeriesName("seriesName1");
        dataSet.getVolumes().add(volume);
        volume = new Volume();
        volume.setName("name2");
        volume.setDescription("description2");
        volume.setTextId("textId2");
        volume.setSetTextId("setTextId2");
        volume.setSetName("setName2");
        volume.setSeriesName("seriesName2");
        dataSet.getVolumes().add(volume);

        return dataSet;
    }

    /**
     * Inserts a dataset.
     *
     * @param dataSet the dataset to insert
     * @return the id
     * @throws Exception to JUnit.
     */
    private long insertDataSet(DataSet dataSet) throws Exception {
        if (dataSet.getReferences() != null) {
            for (Reference reference : dataSet.getReferences()) {
                conversionPersistence.insertReference(reference);
            }
        }

        if (dataSet.getInstruments() != null) {
            for (Instrument instrument : dataSet.getInstruments()) {
                if (instrument.getHosts() != null) {
                    for (InstrumentHost instrumentHost : instrument.getHosts()) {
                        conversionPersistence.insertInstrumentHost(instrumentHost);
                    }
                }
                conversionPersistence.insertInstrument(instrument);
            }
        }

        if (dataSet.getMissions() != null) {
            for (Mission mission : dataSet.getMissions()) {
                conversionPersistence.insertMission(mission);
            }
        }

        if (dataSet.getTargets() != null) {
            for (Target target : dataSet.getTargets()) {
                conversionPersistence.insertTarget(target);
            }
        }

        if (dataSet.getVolumes() != null) {
            for (Volume volume : dataSet.getVolumes()) {
                conversionPersistence.insertVolume(volume);
            }
        }

        return conversionPersistence.insertDataSet(dataSet);
    }
}